package com.ruoyi.system.task;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.datasync.SyncDbSync;
import com.ruoyi.system.mapper.SyncDbSyncMapper;
import com.ruoyi.system.service.ISyncDbSyncService;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;

/**
 * 数据库同步定时任务
 *
 * @author ruoyi
 */
@Component("syncDbTask")
public class SyncDbTask
{
    private static final Logger log = LoggerFactory.getLogger(SyncDbTask.class);

    @Autowired
    private ISyncDbSyncService syncDbSyncService;

    @Autowired
    private SyncDbSyncMapper syncDbSyncMapper;

    /**
     * 执行所有配置了定时任务的同步任务
     */
    public void executeScheduledTasks()
    {
        log.info("定时任务：执行所有到期的数据库同步任务开始");

        try {
            // 获取所有状态为正常且配置了定时任务的同步任务
            List<SyncDbSync> tasks = getScheduledTasks();

            if (tasks.isEmpty()) {
                log.info("没有需要执行的定时同步任务");
                return;
            }

            // 当前时间
            Date now = new Date();

            // 检查每个任务是否到达执行时间
            for (SyncDbSync task : tasks) {
                try {
                    if (isTaskDue(task, now)) {
                        log.info("执行定时同步任务：{}", task.getSyncName());
                        syncDbSyncService.executeSyncTask(task.getSyncId());
                    }
                } catch (Exception e) {
                    log.error("执行同步任务[{}]失败: {}", task.getSyncId(), e.getMessage(), e);
                }
            }
        } catch (Exception e) {
            log.error("执行定时同步任务异常: {}", e.getMessage(), e);
        }

        log.info("定时任务：执行所有到期的数据库同步任务结束");
    }

    /**
     * 获取所有配置了定时任务的同步任务
     */
    private List<SyncDbSync> getScheduledTasks() {
        SyncDbSync query = new SyncDbSync();
        query.setStatus("0"); // 状态正常
        List<SyncDbSync> allTasks = syncDbSyncMapper.selectSyncDbSyncList(query);

        // 过滤出配置了定时任务的同步任务（执行周期不为0-手动）
        allTasks.removeIf(task -> "0".equals(task.getExecCycle()) || StringUtils.isEmpty(task.getExecTime()));

        return allTasks;
    }

    /**
     * 判断任务是否到达执行时间
     */
    private boolean isTaskDue(SyncDbSync task, Date now) {
        // 如果下次执行时间为空，则认为不需要执行
        if (StringUtils.isEmpty(task.getExecTime())) {
            return false;
        }

        try {
            // 解析下次执行时间
            //每天
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if (task.getExecCycle().equals("1")){
                String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm"));
                if (format.equals(task.getExecTime())){
                    return true;
                }
            }
            //每周一
            if (task.getExecCycle().equals("2")){
                boolean isMonday = LocalDate.now().getDayOfWeek().getValue() == 1;
                if (isMonday){
                    String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm"));
                    if (format.equals(task.getExecTime())){
                        return true;
                    }
                }
            }
            //每月
            if (task.getExecCycle().equals("3")){
                boolean isFirstDay = LocalDate.now().getDayOfMonth() == 1;
                if (isFirstDay){
                    String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm"));
                    if (format.equals(task.getExecTime())){
                        return true;
                    }
                }
            }
            // 如果当前时间晚于或等于下次执行时间，则需要执行
//            Date nextExecTime = sdf.parse(task.getExecTime());
//            return !now.before(nextExecTime);
            return false;
        } catch (Exception e) {
            log.error("解析下次执行时间失败: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 执行指定的同步任务
     */
    public void executeTask(String params)
    {
        log.info("手动触发定时任务执行数据库同步，参数: {}", params);

        if (StringUtils.isEmpty(params)) {
            log.error("同步任务ID不能为空");
            return;
        }

        try {
            Long syncId = Long.valueOf(params);
            boolean result = syncDbSyncService.executeSyncTask(syncId);
            log.info("手动触发同步任务[{}]执行结果: {}", syncId, result ? "成功" : "失败");
        } catch (Exception e) {
            log.error("执行同步任务异常: {}", e.getMessage(), e);
        }
    }
}
